package com.hzlj.position.locate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.fz.common.base.core.JsonUtils;
import com.fz.common.base.core.date.DateUtils;
import com.fz.common.base.dto.PageParamDTO;
import com.fz.common.base.dto.QueryPageResultDTO;
import com.fz.common.base.exception.PubError;
import com.fz.common.base.exception.PubException;
import com.fz.common.dict.annotation.DictConvert;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hzlj.common.message.common.dto.webRTC.RTCUserDTO;
import com.hzlj.common.message.common.dto.webRTC.WebRTCReqTO;
import com.hzlj.common.message.common.dto.webRTC.WebRTCResTO;
import com.hzlj.common.message.common.util.MessageRestUtil;
import com.hzlj.common.message.common.util.WebRTCRestUtil;
import com.hzlj.position.config.config.PositionConfig;
import com.hzlj.position.locate.common.dto.reportVideo.*;
import com.hzlj.position.locate.common.dto.reportVideoJzry.ReportVideoJzryUpsertDTO;
import com.hzlj.position.locate.common.enums.VideoStatus;
import com.hzlj.position.locate.common.model.ReportVideo;
import com.hzlj.position.locate.converter.ReportVideoConverter;
import com.hzlj.position.locate.dao.ReportVideoDao;
import com.hzlj.position.locate.service.ReportVideoJzryService;
import com.hzlj.position.locate.service.ReportVideoService;
import com.hzlj.sqjz.config.common.enums.HandleStatus;
import com.hzlj.sqjz.jz.common.dto.common.JzCommonQueryParamDTO;
import com.hzlj.sqjz.jz.common.dto.common.JzSimpleQueryResultDTO;
import com.hzlj.sqjz.jz.service.JzJbxxService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.hzlj.position.config.config.IdConfig.POSITION_ID_GEN;

/**
 * 通信联络核查-视频核验(ReportVideo)表服务接口
 *
 * @author lifh
 * @date 2023-03-13 19:10:16
 */
@Slf4j
@Service
public class ReportVideoServiceImpl implements ReportVideoService {
    @Resource
    private ReportVideoDao reportVideoDao;
    @Resource
    private ReportVideoJzryService reportVideoJzryService;
    @Resource
    private PositionConfig positionConfig;
    @Resource
    private JzJbxxService jzJbxxService;

    /**
     * 通过id查询单条数据
     */
    @Override
    public ReportVideoQueryResultDTO getReportVideoById(String id) {
        ReportVideo reportVideo = this.reportVideoDao.getById(id);
        if (Objects.isNull(reportVideo)) {
            throw new PubException(PubError.NO_OBJECT_FOUND);
        }
        return ReportVideoConverter.from(reportVideo);
    }

    /**
     * 新增数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReportVideoCallResultDTO saveReportVideo(ReportVideoCallDTO dto) {
        List<JzSimpleQueryResultDTO> jzries
                = this.jzJbxxService.listJzJbxxSimple(new JzCommonQueryParamDTO().setJzIds(dto.getJzIds()));
        if (dto.getJzIds().size() != jzries.size()) {
            throw new PubException("选择的人员信息不正确!");
        }

        //发起呼叫参数
        WebRTCReqTO call = new WebRTCReqTO()
                .setOrgCode(jzries.get(0).getJgCode())
                .setCallType(dto.getCallType())
                .setInitiator(new RTCUserDTO().setUserId(dto.getCreatorUid()).setUserName(dto.getCreatorName()))
                .setInvitees(jzries.stream().map(e -> {
                    RTCUserDTO user = new RTCUserDTO();
                    user.setUserId(e.getJzId());
                    user.setUserName(e.getXm());
                    user.setOrgCode(e.getJgCode());
                    return user;
                }).collect(Collectors.toList()));
        //发起呼叫
        WebRTCResTO callResult = WebRTCRestUtil.call(positionConfig.getCommonService().getUrl(), call);
        Date now = new Date();
        //开始新增
        List<ReportVideo> adds = callResult.getInvitees().stream().map(e -> {
            ReportVideo add = new ReportVideo();
            add.setId(POSITION_ID_GEN.nextIdStr());
            add.setJzId(e.getUserId());
            add.setVideoStatus(VideoStatus.CALL.getStatus());
            add.setBussId(callResult.getBussId());
            add.setHandleStatus(HandleStatus.WAIT.getStatus());
            add.setBelongDay(DateUtil.beginOfDay(now));
            add.setSpotCheckTime(now);
            add.setCreatorUid(dto.getCreatorUid());
            add.setCreatorName(dto.getCreatorName());
            add.setCreateTime(now);
            return add;
        }).collect(Collectors.toList());
        this.reportVideoDao.saveBatch(adds);
        //修改人员数据
        List<ReportVideoJzryUpsertDTO> upserts = adds.stream().map(this::convert).collect(Collectors.toList());
        reportVideoJzryService.upsert(true, upserts);

        //发送消息
        this.notice(adds);

        log.info("【视频点验】:新增发起数据:{}", JsonUtils.obj2json(dto));
        return new ReportVideoCallResultDTO().setCallResult(callResult);
    }


    /**
     * 修改数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateReportVideo(VideoStatus status, ReportVideoUpdateDTO dto) {
        Date now = new Date();
        ReportVideo reportVideo = reportVideoDao.getReportVideoByBussId(dto.getBussId(), dto.getJzId());
        if (Objects.isNull(reportVideo)) {
            throw new PubException("没有找到视频发起信息");
        }

        //是否需要处理  0：不需要处理 1：需要处理 2：已处理
        ReportVideo update = new ReportVideo();
        update.setId(reportVideo.getId());
        update.setJzId(reportVideo.getJzId());
        update.setBelongDay(reportVideo.getBelongDay());
        update.setVideoStatus(status.getStatus());
        update.setUpdateTime(now);
        update.setReportAddress(dto.getReportAddress());
        update.setLongitude(dto.getLongitude());
        update.setLatitude(dto.getLatitude());
        switch (status) {
            case ANSWER:
                update.setHandleStatus(HandleStatus.NONE.getStatus());
                update.setVideoStartTime(now);
                break;
            case REJECT:
                update.setHandleStatus(HandleStatus.WAIT.getStatus());
                break;
            case HANGUP:
                update.setHandleStatus(HandleStatus.NONE.getStatus());
                update.setVideoEndTime(now);
                update.setVideoDuration(dto.getVideoDuration());
                break;
            default:
        }
        this.reportVideoDao.updateReportVideo(update);
        //修改矫正人员
        reportVideoJzryService.upsert(false, Lists.newArrayList(this.convert(update)));
    }

    @Override
    public void delete(String jzId, Date date) {
        this.reportVideoDao.delete(jzId, DateUtil.beginOfDay(date));
    }

    @Override
    @DictConvert
    public List<ReportVideoWithJzJbxxDTO> listReportVideo(ReportVideoQueryParamDTO dto) {
        return this.reportVideoDao.listReportVideo(dto);
    }

    /**
     * 查询列表：分页
     */
    @Override
    @DictConvert
    public QueryPageResultDTO<ReportVideoWithJzJbxxDTO> pageReportVideo(ReportVideoQueryParamDTO dto, PageParamDTO page) {
        return this.reportVideoDao.pageReportVideo(dto, page);
    }

    private ReportVideoJzryUpsertDTO convert(ReportVideo reportVideo) {
        ReportVideoJzryUpsertDTO jzryUpsert = BeanUtil.copyProperties(reportVideo, ReportVideoJzryUpsertDTO.class);
        jzryUpsert.setId(reportVideo.getJzId());
        jzryUpsert.setVideoId(reportVideo.getId());
        jzryUpsert.setBelongDay(reportVideo.getBelongDay());
        return jzryUpsert;
    }

    private void notice(List<ReportVideo> reportVideos) {
        for (ReportVideo reportVideo : reportVideos) {
            try {
                String messageTemplate = "report-video";
                Map<String, Object> params = Maps.newHashMap();
                params.put("spotCheckTime", DateUtils.formatDate(new Date()));
                MessageRestUtil.noticeQueryUsers(
                        messageTemplate,
                        reportVideo.getId(),
                        params,
                        false,
                        reportVideo.getJzId()
                );
            } catch (Exception e) {
                log.error("发送视频核查消息失败[通知矫正人员]报错:{}", reportVideo, e);
            }
        }
    }

}
